package com.suray.rgv.son.mother;

import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.utils.LoggerType;
import com.suray.commin.exception.Rgv60TaskException;
import com.suray.rgv.RgvSMInterface;
import com.suray.rgv.data.Rgv60InfoData;
import com.suray.rgv.data.RgvSMInfoData;
import com.suray.rgv.son.mother.core.RgvSMCore;
import com.suray.rgv.son.mother.test.RgvTest;
import com.suray.rgv.util.ErrorInfo;
import com.suray.rgv.util.RgvLogger;
import com.suray.rgv60.generate.GeneralMapManage;
import com.suray.rgv60.util.Rgv60ErrorUtil;
import com.suray.type.Rgv60PalletStatus;
import com.suray.type.Rgv60Status;
import com.suray.wcs.res.enums.Order;
import com.suray.wcs.res.enums.PalletStatus;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.res.enums.RgvType;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 子母车实体类，实现接口RgvSMInterface
 */
public class RgvSMImpl implements RgvSMInterface {
    /**
     * 6代车核心
     */
    private final RgvSMCore rgvSMCore;

    /**
     * 小车序列号
     */
    private String serialNum;

    /**
     * 小车ip
     */
    private String ip;

    public RgvSMImpl(int rgvNo, String serialNum, String ip) {
        this.serialNum = serialNum;
        this.rgvSMCore = new RgvSMCore(rgvNo, serialNum);
        this.ip = ip;

        rgvSMCore.start();

        new RgvTest(this);
    }

    public void run() {
        try {
//            rgvSMCore.run();
        } catch (Throwable e) {
            RgvLogger.exceptionLog(LoggerType.ERROR, null, serialNum + " 运行", e, this.getClass());
        }
    }

    @Override
    public void init() {
        try {
            rgvSMCore.init(ip);
        } catch (Throwable e) {
            RgvLogger.exceptionLog(LoggerType.ERROR, null, serialNum + " 初始化", e, this.getClass());
        }
    }

    @Override
    public void initNet(String ip, int port) {
        rgvSMCore.initNet(ip);
    }

    @Override
    public String getSeries() {
        return serialNum;
    }

    @Override
    public void generalTask(Integer taskId, List<Node> nodeList) {
        rgvSMCore.generalTask(taskId, nodeList);
    }

    @Override
    public void sonRgvSendTask(Object taskId, int rgvSonTaskId, List<Node> nodeList, int[] pathIndexs,
                               boolean startTask) throws IOException {
        rgvSMCore.checkSonRgvCanDoTask();
        rgvSMCore.generalSonRgvTask(taskId, rgvSonTaskId, nodeList, pathIndexs, startTask);
    }

    @Override
    public void sonRgvTaskStart() throws IOException {
        rgvSMCore.sonRgvTaskStart();
    }

    @Override
    public int getRgvSonEndSegment(int resTaskId, long taskTime) {
        return rgvSMCore.getRgvSonEndSegment(resTaskId, taskTime);
    }

    @Override
    public boolean isRgvSonTaskEnd(int wcsTaskId, int resTaskId, long taskTime) {
        return rgvSMCore.isRgvSonTaskEnd(wcsTaskId, resTaskId, taskTime);
    }

    @Override
    public boolean task(Object taskId, List<Node> pathNodes) {
        return rgvSMCore.task(taskId, pathNodes);
    }

    @Override
    public boolean isTaskEnd(int taskId) {
        return rgvSMCore.isTaskEnd(taskId);
    }

    @Override
    public boolean isActionEnd(Order action) {
        return false;
    }

    @Override
    public Object getTaskId() {
        return rgvSMCore.getTaskId();
    }

    @Override
    public int getTaskNo() {
        return 0;
    }

    @Override
    public boolean action(Order rgvActionType) {
        try {
            return rgvSMCore.action(rgvActionType, null);
        } catch (IOException e) {
            throw new RuntimeException(rgvActionType + "时, 执行失败, 通讯异常");
        }
    }

    @Override
    public boolean action(Order rgvActionType, Object actionParam) {
        try {
            return rgvSMCore.action(rgvActionType, actionParam);
        } catch (IOException e) {
            throw new Rgv60TaskException(rgvActionType.getOrderDescribe() + " 执行失败");
        }
    }

    @Override
    public boolean changeLocation(Node node) {
        //TODO MJ RGV60
        //只能行驶到某个点，暂不提供该功能
        return false;
    }

    @Override
    public ErrorInfo getErrorInfo() {
        return rgvSMCore.getMaxError();
    }

    @Override
    public List<ErrorInfo> getErrorInfos() {
        return rgvSMCore.getErrors();
    }

    @Override
    public void clearError(ErrorInfo error) {
        rgvSMCore.removeError(error);
    }

    @Override
    public void clearAllError() throws IOException {
        rgvSMCore.clearFault();
    }

    @Override
    public void clearTask() throws IOException {
        rgvSMCore.clearTask();
    }

    @Override
    public boolean recovery() throws IOException {
        return rgvSMCore.recovery();
    }

    @Override
    public Node getLocation() {
        return rgvSMCore.getLocation();
    }

    @Override
    public RgvStatus getRgvStatus() {
        Rgv60Status rgv60Status = rgvSMCore.getRgvStatus();

        switch (rgv60Status) {
            case RUNNING:
            case SON_RGV_RUNNING:
                return RgvStatus.RUNING;
            case STANDY:
                if (rgvSMCore.hasTask()) {
                    return RgvStatus.NODE_STANDBY;
                }
                return RgvStatus.READY;
            case ERROR:
                return RgvStatus.ERROR;
            case STOP:
                return RgvStatus.PAUSE;
            case NONE:
            case INIT:
                return RgvStatus.UNKNOWN;
            case OFF_LINE:
                return RgvStatus.OFF_LINE;
            case SON_RGV_WAITING:
            case WAITING:
                return RgvStatus.NODE_STANDBY;
            default:
                break;
        }
        return null;
    }

    @Override
    public PalletStatus getRgvPalletStatus() {
        Rgv60PalletStatus rgv60PalletStatus =  rgvSMCore.getPalletStatus();
        PalletStatus palletStatus;

        switch (rgv60PalletStatus) {
            case STOP:
            case FAIL:
            case ERROR:
                palletStatus = PalletStatus.ERROR;
                break;
            case DOWNING:
            case UP_OK:
                palletStatus = PalletStatus.UP;
                break;
            case UPING:
            case DOWN_OK:
                palletStatus = PalletStatus.DOWN;
                break;
            case INVALID:
            default:
                palletStatus = PalletStatus.UNKNOWN;
                break;
        }

        return palletStatus;
    }

    @Override
    public Float getBatSoc() {
        return rgvSMCore.getBatSoc();
    }

    @Override
    public Float getBatTemp() {
        return rgvSMCore.getBatTemp();
    }

    @Override
    public Float getBatVolt() {
        return rgvSMCore.getBatVolt();
    }

    @Override
    public Float getBatCurrent() {
        return rgvSMCore.getBatCur();
    }

    @Override
    public Integer getBatChargeNum() {
        return rgvSMCore.getChargeNum();
    }

    @Override
    public Float getAutoChargeBattery() {
        return rgvSMCore.getPermitChargeVolt();
    }

    @Override
    public Integer getForceChargeBattery() {
        return null;
    }

    @Override
    public boolean isForbidden() {
        return false;
    }

    @Override
    public boolean isAutoCharge() {
        return false;
    }

    @Override
    public boolean isRgvValid() {
        return true;
    }

    @Override
    public String getNetId() {
        return ip;
    }

    @Override
    public String getMap() {
        return rgvSMCore.getMap();
    }

    @Override
    public int getRgvNo() {
        return 0;
    }

    @Override
    public boolean stopTask() {
        return false;
    }

    @Override
    public void cancelTask(int taskId) {

    }

    @Override
    public boolean emergencyStop() {
        return rgvSMCore.emergencyStop();
    }

    @Override
    public RgvType getRgvType() {
        return RgvType.RGV_SON_MOTHER;
    }

    @Override
    public void sendMap(String wareHouse) throws IOException {
        List<File> files = GeneralMapManage.getMapFiles(wareHouse);
        rgvSMCore.sendMap(files);
    }

    @Override
    public String downloadMap(String mapName) throws IOException {
        return null;
    }

    @Override
    public void deleteMap(String mapName) throws IOException {

    }

    @Override
    public String getName() {
        return rgvSMCore.getRobotName();
    }

    @Override
    public boolean isOnline() {
        return rgvSMCore.isOnLine();
    }

    @Override
    public void setInterrupt() throws IOException {
        rgvSMCore.setInterrupt();
    }

    @Override
    public void rgvError(ErrorInfo errorInfo) {
        rgvSMCore.rgvError(errorInfo);
    }

    @Override
    public void forwardRun() {
        rgvSMCore.forwardRun();
    }

    @Override
    public void fallBackRun() {
        rgvSMCore.fallBackRun();
    }

    @Override
    public void turnLeft() {
        rgvSMCore.turnLeft();
    }

    @Override
    public void turnRight() {
        rgvSMCore.turnRight();
    }

    @Override
    public void stopManualMove() {
        rgvSMCore.stopManualMove();
    }

    @Override
    public boolean isCharging() {
        return false;
    }

    @Override
    public boolean isStatic() {
        return rgvSMCore.isStatic();
    }

    @Override
    public boolean positionOk() {
        return rgvSMCore.positionOk();
    }

    @Override
    public void destroy() {
        rgvSMCore.endThread();
    }

    @Override
    public void changeMap(int layer) throws IOException {
        rgvSMCore.changeMap(layer);
    }

    @Override
    public Integer getCurrentFloor() {
        return rgvSMCore.getCurrentFloor();
    }

    @Override
    public Boolean hasPallet() {
        return rgvSMCore.hasPallet();
    }

    @Override
    public Rgv60InfoData getRgv60InfoData() {
        throw new RuntimeException("子母车获取数据请使用getRgvSMInfoData接口");
    }

    @Override
    public void changeAuthor(boolean hasAuthor) throws IOException {
        rgvSMCore.changeAuthor(hasAuthor);
    }

    @Override
    public boolean hasAuthor() {
        return rgvSMCore.hasAuthor();
    }

    @Override
    public void resetPosition() throws IOException {
        rgvSMCore.resetPosition();
    }

    @Override
    public void setMapNodes(List<Node> nodes) {
        rgvSMCore.setMapNodes(nodes);
    }

    @Override
    public void updateMapNode(Node node) {
        rgvSMCore.updateMapNode(node);
    }

    @Override
    public String getSonRgvGroundCode() {
        return rgvSMCore.getSonRgvGroundCode();
    }

    @Override
    public boolean isSonRgvInMother() {
        return rgvSMCore.isSonRgvInMother();
    }

    @Override
    public void sonRgvMoveBySpeed(Integer direction) {
        rgvSMCore.sonRgvMoveBySpeed(direction);
    }

    @Override
    public void stopSonRgvMoveBySpeed() {
        rgvSMCore.stopSonRgvMoveBySpeed();
    }

    @Override
    public void sonRgvMoveByDistance(Integer direction) {
        rgvSMCore.checkSonRgvCanDoTask();
        rgvSMCore.sonRgvMoveByDistance(direction);
    }

    @Override
    public void sonRgvRecovery() {
        rgvSMCore.sonRgvRecovery();
    }

    @Override
    public void sonRgvCharge() {
        rgvSMCore.checkSonRgvCanDoTask();
        rgvSMCore.sonRgvCharge();
    }

    @Override
    public void sonRgvStopCharge() {
        rgvSMCore.checkSonRgvCanDoTask();
        rgvSMCore.sonRgvStopCharge();
    }

    @Override
    public void sonRgvChangeSpeedConfig(Integer moveSpeed, Integer moveSpeedAcc, Integer moveSpeedDec) {
        rgvSMCore.sonRgvChangeSpeedConfig(moveSpeed, moveSpeedAcc, moveSpeedDec);
    }

    @Override
    public void setSonRgvDirectionX(Boolean rgvDirection) {
        rgvSMCore.setRgvDirectionX(rgvDirection);
    }

    @Override
    public void setSonRgvDirectionY(Boolean rgvDirection) {
        rgvSMCore.setRgvDirectionY(rgvDirection);
    }

    @Override
    public void sonRgvCalibration() {
        rgvSMCore.checkSonRgvCanDoTask();
        rgvSMCore.sonRgvCalibration();
    }

    @Override
    public String getSonGroundCodeInMother() {
        return rgvSMCore.getSonGroundCodeInMother();
    }

    @Override
    public void setSonGroundCodeInMother(String sonGroundCodeInMother) {
        rgvSMCore.setSonGroundCodeInMother(sonGroundCodeInMother);
    }

    @Override
    public boolean hasTask() {
        return rgvSMCore.hasTask();
    }

    @Override
    public void endTask(Object taskId) {
        rgvSMCore.endTask(taskId);
    }

    @Override
    public boolean isAllSendTaskEnd() {
        return rgvSMCore.isAllSendTaskEnd();
    }

    @Override
    public void setError(String message) {
        rgvSMCore.setRgvError(Rgv60ErrorUtil.SYSTEM_SET_ERROR.getCode(), message, Rgv60ErrorUtil.SYSTEM_SET_ERROR.getLevel());
    }

    @Override
    public void sonRgvClearTask() {
        rgvSMCore.sonRgvClearTask();
    }

    @Override
    public RgvStatus getSonRgvStatus() {
        return rgvSMCore.getSonRgvStatus();
    }

    @Override
    public int getSonRgvTaskErrorCode() {
        return rgvSMCore.getSonRgvTaskErrorCode();
    }

    @Override
    public void enableSonRgv() {
        rgvSMCore.enableSonRgv();
    }

    @Override
    public void disableSonRgv() {
        rgvSMCore.disableSonRgv();
    }

    @Override
    public boolean isMotherOnline() {
        return rgvSMCore.isMotherOnline();
    }

    @Override
    public boolean isSonRgvInMotherNoComm() {
        return rgvSMCore.isSonRgvInMotherNoComm();
    }

    @Override
    public boolean isSonRgvTaskError() {
        return rgvSMCore.isSonRgvTaskError();
    }

    @Override
    public void changeSonRgv(Object rgvSon) {
        rgvSMCore.changeSonRgv(rgvSon);
    }

    @Override
    public RgvSMInfoData getRgvSMInfoData() {
        return rgvSMCore.getRgv60InfoData();
    }
}
